import * as THREE from '../../build/three.module.js';
import { GUI } from '../../jsm/libs/dat.gui.module.js';
import { OrbitControls } from '../../jsm/controls/OrbitControls.js';
import { Lut } from '../../jsm/math/Lut.js';

const lut = new Lut();

const scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
const perpCamera = new THREE.PerspectiveCamera(65, innerWidth / innerHeight, 1, 100);
perpCamera.position.set(0, 0, 10);
scene.add(perpCamera);
const mesh = new THREE.Mesh(undefined, new THREE.MeshLambertMaterial({
  side: THREE.DoubleSide,
  color: 0xf5f5f5,
  vertexColors: true
}));
scene.add(mesh);

// 创建色带视图
const uiScene = new THREE.Scene();
const orthoCamera = new THREE.OrthographicCamera(- 1, 1, 1, - 1, 1, 2);
orthoCamera.position.set(.5, 0, 1);
const sprite = new THREE.Sprite(new THREE.SpriteMaterial({
  map: new THREE.CanvasTexture( lut.createCanvas() )
}));
sprite.scale.x = .125;
uiScene.add(sprite);

// 主场景光源
const pointLight = new THREE.PointLight(0xffffff, 1);
perpCamera.add(pointLight);

// 创建渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.autoClear = false;
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

// 渲染函数
const render = () => {
  renderer.clear();
  renderer.render(scene, perpCamera);
  renderer.render(uiScene, orthoCamera);
}
render();

// 更新色彩模型
const params = { // 色彩模型参数
  colorMap: 'rainbow',
  min: -432,
  max: 2392 
}
const updateColors = () => {
  lut.setColorMap(params.colorMap);
  lut.setMin(params.min);
  lut.setMax(params.max);

  const geo = mesh.geometry;
  const pressure = geo.attributes.pressure;
  const colors = geo.attributes.color;
  let min = 0, max = 0;
  for(let i = 0; i < pressure.array.length; i += 1) {
    const colorValue = pressure.array[i];
    if (colorValue > max) {
      max = colorValue;
    }
    if (colorValue < min) {
      min = colorValue
    }
    const color = lut.getColor(colorValue);
    if (color === undefined) {
      console.log(`颜色值${colorValue}无法进行转换`);
    } else {
      colors.setXYZ(i, color.r, color.g, color.b);
    }
  }
  console.log(min, max);
  colors.needsUpdate = true;
  
  const map = sprite.material.map;
  lut.updateCanvas( map.image );
  map.needsUpdate = true;
}

// 模型加载
const loadModel = () => {
  const loader = new THREE.BufferGeometryLoader();
  loader.load('../../models/json/pressure.json', geo => {

    geo.center();
    geo.computeVertexNormals();

    // 设置默认顶点着色
    const colors = [];
    for(let i = 0; i < geo.attributes.position.count; i += 1) {
      colors.push(1, 1, 1);
    }
    geo.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));

    mesh.geometry = geo;
    updateColors();
    render();
  })
}
loadModel();

// GUI 控制
const gui = new GUI();
gui.add(params, 'colorMap', [
  'rainbow', 'cooltowarm', 'blackbody', 'grayscale'
]).onChange(() => {
  updateColors();
  render();
});
gui.add(params, 'min').onChange(() => {
  updateColors();
  render();
});
gui.add(params, 'max').onChange(() => {
  updateColors();
  render();
});

// 处理窗口尺寸变化
const handleWindowResize = () => {
  perpCamera.aspect = innerWidth / innerHeight;
  perpCamera.updateProjectionMatrix();
  renderer.setSize(innerWidth, innerHeight);
  render();
}

// 监听操作
window.addEventListener('resize', handleWindowResize);

// 添加控制器
const controls = new OrbitControls(perpCamera, renderer.domElement);
controls.addEventListener('change', render);
